package handlers

import (
	"restaurant-system/internal/models"
	"restaurant-system/pkg/utils"

	"errors"
	"net/http"

	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type RegisterRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
	Phone    string `json:"phone" binding:"required"`
	Email    string `json:"email" binding:"required,email"`
}

type LoginRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
}

// 添加 UserHandler 结构体
type UserHandler struct {
	DB *gorm.DB
}

// 添加 NewUserHandler 构造函数
func NewUserHandler(db *gorm.DB) *UserHandler {
	return &UserHandler{
		DB: db,
	}
}

func (h *UserHandler) Register(c *gin.Context) {
	var req RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 检查用户名是否已存在
	var existingUser models.User
	if err := h.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil {
		c.JSON(400, gin.H{"error": "用户名已存在"})
		return
	}

	// 创建用户
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		c.JSON(500, gin.H{"error": "密码加密失败"})
		return
	}

	user := models.User{
		Username: req.Username,
		Password: string(hashedPassword),
		Phone:    req.Phone,
		Email:    req.Email,
		Status:   "active",
		Role:     "user",
		Points:   0,
	}

	if err := h.DB.Create(&user).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建用户失败"})
		return
	}

	// 创建用户偏好设置
	preference := models.UserPreference{
		UserID:         user.ID,
		FavCategories:  []string{},
		FavTags:        []string{},
		SpicyLevel:     0,
		DietaryNeeds:   []string{},
		Allergies:      []string{},
		DislikedDishes: []uint{},
	}

	if err := h.DB.Create(&preference).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建用户偏好失败"})
		return
	}

	// 生成 JWT token
	token, err := utils.GenerateToken(user.ID, false)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
		return
	}

	c.JSON(200, gin.H{
		"message": "注册成功",
		"user":    user,
		"token":   token,
	})
}

func (h *UserHandler) Login(c *gin.Context) {
	var req LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	var user models.User
	if err := h.DB.Where("username = ?", req.Username).First(&user).Error; err != nil {
		c.JSON(401, gin.H{"error": "用户名或密码错误"})
		return
	}

	if !utils.CheckPasswordHash(req.Password, user.Password) {
		c.JSON(401, gin.H{"error": "用户名或密码错误"})
		return
	}

	// 生成 JWT token
	token, err := utils.GenerateToken(user.ID, user.IsAdmin)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
		return
	}

	c.JSON(200, gin.H{
		"token": token,
		"user": gin.H{
			"id":       user.ID,
			"username": user.Username,
			"email":    user.Email,
			"phone":    user.Phone,
			"points":   user.Points,
			"role":     user.Role,
			"avatar":   user.Avatar,
		},
	})
}

// 获取用户列表
func (h *UserHandler) GetUsers(c *gin.Context) {
	var users []models.User

	if err := h.DB.Find(&users).Error; err != nil {
		c.JSON(500, gin.H{"error": "获取用户列表失败"})
		return
	}

	c.JSON(200, gin.H{"users": users})
}

// 获取单个用户详情
func (h *UserHandler) GetUser(c *gin.Context) {
	id := c.Param("id")
	var user models.User

	if err := h.DB.First(&user, id).Error; err != nil {
		c.JSON(404, gin.H{"error": "用户不存在"})
		return
	}

	c.JSON(200, gin.H{"user": user})
}

// 更新用户信息
func (h *UserHandler) UpdateUser(c *gin.Context) {
	id := c.Param("id")
	var user models.User

	// 先检查用户是否存在
	if err := h.DB.First(&user, id).Error; err != nil {
		c.JSON(404, gin.H{"error": "用户不存在"})
		return
	}

	// 绑定请求数据
	var req struct {
		Email    string `json:"email"`
		Phone    string `json:"phone"`
		Username string `json:"username"`
		Avatar   string `json:"avatar"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 如果要更新用户名，先检查是否已存在
	if req.Username != "" && req.Username != user.Username {
		var existingUser models.User
		if err := h.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil {
			c.JSON(400, gin.H{"error": "用户名已存在"})
			return
		}
	}

	// 更新用户信息
	updates := map[string]interface{}{
		"email":    req.Email,
		"phone":    req.Phone,
		"username": req.Username,
		"avatar":   req.Avatar,
	}

	// 只更新非空字段
	for k, v := range updates {
		if v == "" {
			delete(updates, k)
		}
	}

	if err := h.DB.Model(&user).Updates(updates).Error; err != nil {
		c.JSON(500, gin.H{"error": "更新用户信息失败"})
		return
	}

	// 返回更新后的用户信息
	c.JSON(200, gin.H{
		"message": "更新成功",
		"user": gin.H{
			"ID":       user.ID,
			"username": user.Username,
			"email":    user.Email,
			"phone":    user.Phone,
			"avatar":   user.Avatar,
			"points":   user.Points,
			"role":     user.Role,
			"status":   user.Status,
		},
	})
}

// 删除用户
func (h *UserHandler) DeleteUser(c *gin.Context) {
	id := c.Param("id")

	if err := h.DB.Delete(&models.User{}, id).Error; err != nil {
		c.JSON(500, gin.H{"error": "删除用户失败"})
		return
	}

	c.JSON(200, gin.H{"message": "删除成功"})
}

// GetCurrentUser 获取当前登录用户的信息
func (h *UserHandler) GetCurrentUser(c *gin.Context) {
	userID, exists := c.Get("userID")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未找到用户信息"})
		return
	}

	var user models.User
	if err := h.DB.First(&user, userID).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户信息失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"ID":       user.ID,
		"username": user.Username,
		"email":    user.Email,
		"phone":    user.Phone,
		"role":     user.Role,
	})
}
